#include "Rp2Light.h"
#include "Rp2Matrix3.h"

using namespace Rp2;

RP2_IMPLEMENT_RTTI(Rp2, Light, Object);
RP2_IMPLEMENT_DEFAULT_NAME_ID(Light, Object);

const char* Light::ms_aacType[LT_QUANTITY] =
{
    "LT_AMBIENT",
    "LT_DIRECTIONAL",
    "LT_POINT",
    "LT_SPOT"
};

//----------------------------------------------------------------------------
Light::Light ()
    :
    Type(LT_AMBIENT),
    Ambient(0.0f,0.0f,0.0f),
    Diffuse(0.0f,0.0f,0.0f),
    Specular(0.0f,0.0f,0.0f),
    Position(0.0f,0.0f,0.0f),
    DVector(0.0f,0.0f,0.0f),
    UVector(0.0f,0.0f,0.0f),
    RVector(0.0f,0.0f,0.0f)
{
    Constant = 0.0f;
    Linear = 0.0f;
    Quadratic = 0.0f;
    Intensity = 0.0f;
    Angle = 0.0f;
    CosAngle = 0.0f;
    SinAngle = 0.0f;
    Exponent = 0.0f;
}
//----------------------------------------------------------------------------
Light::Light (LightType eType)
    :
    Type(eType),
    Ambient(0.0f,0.0f,0.0f),
    Diffuse(0.0f,0.0f,0.0f),
    Specular(0.0f,0.0f,0.0f),
    Position(0.0f,0.0f,0.0f),
    DVector(0.0f,0.0f,-1.0f),
    UVector(0.0f,1.0f,0.0f),
    RVector(1.0f,0.0f,0.0f)
{
    Constant = 1.0f;
    Linear = 0.0f;
    Quadratic = 0.0f;
    Intensity = 1.0f;
    Angle = Mathf::PI;
    CosAngle = -1.0f;
    SinAngle = 0.0f;
    Exponent = 1.0f;
}
//----------------------------------------------------------------------------
Light::~Light ()
{
}
//----------------------------------------------------------------------------
void Light::SetAngle (float fAngle)
{
    assert(0.0f < fAngle && fAngle <= Mathf::PI);
    Angle = fAngle;
    CosAngle = Mathf::Cos(fAngle);
    SinAngle = Mathf::Sin(fAngle);
}
//----------------------------------------------------------------------------
void Light::SetDirection (const Vector3f& rkDirection)
{
    DVector = rkDirection;
    Vector3f::GenerateOrthonormalBasis(UVector,RVector,DVector);
}
//----------------------------------------------------------------------------
bool Light::IsValidFrame () const
{
    float fTest = DVector.Dot(UVector);
    if (Mathf::FAbs(fTest) > Mathf::ZERO_TOLERANCE)
    {
        return false;
    }

    fTest = DVector.Dot(RVector);
    if (Mathf::FAbs(fTest) > Mathf::ZERO_TOLERANCE)
    {
        return false;
    }

    fTest = UVector.Dot(RVector);
    if (Mathf::FAbs(fTest) > Mathf::ZERO_TOLERANCE)
    {
        return false;
    }

    fTest = DVector.Dot(UVector.Cross(RVector));
    return Mathf::FAbs(1.0f - fTest) <= Mathf::ZERO_TOLERANCE;
}
//----------------------------------------------------------------------------
